<?php
/**
 * Created by PhpStorm
 * User: 龍zero
 * Date: 2022-04-10
 * Time: 16:28
 */
declare(strict_types=1);
namespace App\Service;


use App\Exception\ForbiddenException;
use App\Exception\ParameterException;
use App\Lib\Enum\GroupLevel;
use App\Lib\Tools\Paginator;
use App\Model\LinGroup;
use App\Model\LinGroupPermission;
use App\Model\LinPermission;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;

class AdminService
{

    /**
     * @Inject()
     * @var UserService
     */
    private $userService;

    /**
     * @Inject()
     * @var GroupService
     */
    private $groupService;

    /**
     * @Inject()
     * @var UserIdentityService
     */
    private $userIdentityService;

    public function getGroup($id){
        return $this->groupService->getGroupAndPermissions($id);
    }

    public function createGroup(array $params){
        $group = LinGroup::where('name',$params['name'])->first();
        if($group){
            throw new ParameterException([
                'code' => 10004
            ]);
        }
        Db::beginTransaction();
        try{
            $linGroup = new LinGroup();
            $linGroup->name = $params['name'];
            $linGroup->info = $params['info'];
            $linGroup->level = GroupLevel::USER;
            $linGroup->save();
            #权限验证
            if(isset($params['permission_ids']) && $params['permission_ids']){
                $inserts = [];
                $permissions = LinPermission::whereIn('id',$params['permission_ids'])->get();
                foreach ($permissions as $permission){
                    $inserts[] = [
                        'group_id' => $linGroup->id,
                        'permission_id' => $permission->id
                    ];
                }
                LinGroupPermission::insert($inserts);
            }
            Db::commit();
        }catch (\Exception $e){
            Db::rollBack();
            throw $e;
        }
    }


    /**
     * 获取结构化的权限信息
     */
    public function getAllStructuralPermissions(){
        $permissions = LinPermission::where('mount',1)->get()->makeHidden(['mount'])->toArray();
        $structuralArr = [];
        foreach ($permissions as $permission){
            $structuralArr[$permission['module']][] = $permission;
        }
        return $structuralArr;
    }

    public function getUserPageByGroupId($groupId,int $count,int $page){
        $users = $this->userService->getUserPageByGroupId($groupId,$count,$page)->toArray();
        foreach ($users['items'] as  &$user){
            $groups = $this->groupService->getUserGroupsByUserID($user['id']);
            $user['groups'] = $groups;
        }
        return $users;
    }

    public function changeUserPassword($id,array $params){
        $this->userIdentityService->changePassword($id,$params['new_password']);
    }

    public function updateUser($id,array $params){
        $rootGroupId = $this->groupService->getParticularGroupIdByLevel(GroupLevel::ROOT);
        if(in_array($rootGroupId,$params['group_ids'])){
            throw new ForbiddenException(10073);
        }
        $existGroupIds = $this->groupService->getUserGroupIdsByUserId($id);
        if($addGroups = array_diff($params['group_ids'],$existGroupIds)){
            #要添加的权限组
            $this->groupService->addUserGroupRelations($id,$addGroups);
        }
        if($removeGroups = array_diff($existGroupIds,$params['group_ids'])){
            #要移除的权限组
            $this->groupService->deleteUserGroupRelations($id,$removeGroups);
        }
    }

    public function deleteUser($id){
        $userIds = $this->userService->getRootUserIds();
        if(in_array($id,$userIds)){
            throw new ForbiddenException(10079);
        }
        $this->userService->removeById($id);
    }

    public function getAllGroups(){
        #不显示超管分组
        $rootGroupId = $this->groupService->getParticularGroupIdByLevel(GroupLevel::ROOT);
        return $this->groupService->getParticularList($rootGroupId);
    }

    public function dispatchPermissions(array $params){
        $insert = [];
        foreach ($params['permission_ids'] as $permissionId){
            $insert[] = [
                'group_id'=>$params['group_id'],
                'permission_id' => $permissionId
                ];
        }
        return LinGroupPermission::insert($insert);
    }

    public function removePermissions(array $params){
        return LinGroupPermission::query()
            ->where('group_id',$params['group_id'])
            ->whereIn('permission_id',$params['permission_ids'])
            ->delete();
    }
}